package sg.edu.nus.iss.vmcs.machinery;

/*
 * Copyright 2003 ISS.
 * The contents contained in this document may not be reproduced in any
 * form or by any means, without the written permission of ISS, other
 * than for the purpose for which it has been supplied.
 *
 */

import java.io.IOException;
import java.util.Observable;
import java.util.Observer;

import sg.edu.nus.iss.vmcs.store.Coin;
import sg.edu.nus.iss.vmcs.store.StoreController;
import sg.edu.nus.iss.vmcs.system.MainController;
import sg.edu.nus.iss.vmcs.system.SimulatorControlPanel;
import sg.edu.nus.iss.vmcs.util.MessageDialog;
import sg.edu.nus.iss.vmcs.util.VMCSException;

/**
 *
 *
 * @version 3.0 5/07/2003
 * @author Olivo Miotto, Pang Ping Li
 */

public class MachineryController implements Observer {

    public MainController mainCtrl;
    public StoreController storeCtrl;

    private MachinerySimulatorPanel ml;
    private Door door;

    public MachineryController(MainController mctrl){
        mainCtrl = mctrl;
        storeCtrl = mctrl.getStoreController();
    }

    public MainController getMainController() {
        return mainCtrl;
    }
    
    /**
     * change description - applying Observer pattern
     * {@code included
     * 		storeCtrl.initialize();
     * }
     * 
     * @author praveen
     */

    public void initialize() throws VMCSException, IOException {
        storeCtrl.initialize(this);
        door = new Door();
    }

    public void closeDown() {
        if (ml != null)
            ml.dispose();
    }

    /* ************************************************************
     * Panel Operations
     */

    public void displayMachineryPanel() {
        SimulatorControlPanel scp = mainCtrl.getSimulatorControlPanel();
        if (ml == null)
            ml = new MachinerySimulatorPanel(scp, this);
        ml.display();
        //System.out.println("get door status:" + door.isDoorClosed());
        scp.setActive(SimulatorControlPanel.ACT_MACHINERY, false);
    }

    public void closeMachineryPanel() {
        if (ml == null)
            return;
        boolean ds = isDoorClosed();

        if (ds == false) {
            MessageDialog msg =
                new MessageDialog(ml, "Please Lock the Door before You Leave");
            return;
        }
        ml.dispose();
        SimulatorControlPanel scp = mainCtrl.getSimulatorControlPanel();
        scp.setActive(SimulatorControlPanel.ACT_MACHINERY, true);
    }

    /* ************************************************************
     * Door operation
     */

    public boolean isDoorClosed() {
        return door.isDoorClosed();
    }

    public void setDoorState(boolean state) {
        //System.out.println("StoreController.setDoorState:" + state);
        door.setState(state);
        displayDoorState();
    }

    /* ************************************************************
     * Display operation
     */

    public void displayDoorState() {
        if (ml == null)
            return;
        ml.setDoorState(door.isDoorClosed());
    }

    // update drink stock view;
    public void displayDrinkStock() throws VMCSException {
        if (ml == null)
            return;
        ml.getDrinksStoreDisplay().update();
    }

    // update coin stock view after transfer all cash;
    public void displayCoinStock() throws VMCSException {
        if (ml == null)
            return;
        ml.getCashStoreDisplay().update();
    }

    /* ************************************************************
     * Interactions with the Store that need to update the display
     */

    public void storeCoin(Coin c) throws VMCSException {
        storeCtrl.storeCoin(c);
//        if (ml != null)
//            ml.getCashStoreDisplay().update();
    }

    public void dispenseDrink(int idx) throws VMCSException {
        storeCtrl.dispenseDrink(idx);
        if (ml != null)
            ml.getCashStoreDisplay().update();

    }

    public void giveChange(int idx, int numOfCoins) throws VMCSException {
        storeCtrl.giveChange(idx, numOfCoins);
//        if (ml != null)
//            ml.getCashStoreDisplay().update();
    }
    
    /**
     * change description - applying Observer pattern
     * {@code included
     * 		implementing update() method for Observer interface
     * 		displayCoinStock(), displayDrinkStock() moved in from other 
     * 		coin count, drink count manipulating  
     * 		methods into this method
     * }
     * 
     * @author praveen
     */
	@Override
	public void update(Observable arg0, Object arg1) {		
		System.out.println("MachineryController.update() - this observer has been notified");
		System.out.println("MachineryController.update() - update coin count to Display");
		try {
			displayCoinStock();
		} catch (VMCSException e) {
			e.printStackTrace();
			System.out.println("ERROR - could not refresh Coin display");
		}
		System.out.println("MachineryController.update() - update coin count to Store");
		try {
			displayDrinkStock();
		} catch (VMCSException e) {			
			e.printStackTrace();
			System.out.println("ERROR - could not refresh Drink display");
		}
	}
}
